<?php
namespace app\models;
/**
 * @desc 盘点功能模型
 * @author liaojianwen
 * @date 2017-01-17
 */

use app\models\BaseModel;
use app\enum\EnumOther;
use app\dao\StockPileDAO;
use app\dao\InventoryDAO;
use app\dao\InventoryDetailDAO;
use Yii;
use app\dao\InventoryFullDAO;
use app\dao\InventoryLostDAO;
use app\enum\EnumOriginType;
use app\dao\InventoryFullDetailDAO;
use app\dao\InventoryLostDetailDAO;
use app\helpers\Utility;
use app\dao\ProductDAO;
use app\dao\ProductUpdateLogDAO;
use app\dao\TransactionDAO;
use app\dao\WarehouseDAO;
use app\dao\PriceTransactionDAO;
use app\helpers\ImageHelper;
use app\helpers\FileUploader;

class InventoryModel extends BaseModel
{
	/**
	 * @desc 覆盖父方法返回对象
	 * @author liaojianwen
	 * @date 2017-01-17
	 * @return InventoryModel
	 */
	public static function model($className=__CLASS__)
	{
		return parent::model($className);
	}
	
	/**
	 * @desc 根据仓库id获取仓库内的商品列表
	 * @param $ware_id 仓库id
	 * @param [] $name 查询条件
	 * @param $pageInfo 页面信息 
	 * @author liaojianwen
	 * @date 2017-01-18
	 */
	public function getProductByWare($ware_id, $name, $pageInfo)
	{
		if(!$ware_id){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'warehouse_id is empty');
		}
		$result = StockPileDAO::getInstance()->getProductByWare($ware_id, $name, $pageInfo);
		if(empty($result)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'no data found');
		}
		return $this->handleApiFormat(EnumOther::ACK_SUCCESS, $result);
	}
	
	/**
	 * @desc 保存盘点单
	 * @param [] $head 盘点单单头
	 * @param [] $detail 盘点单明细
	 * @param [] $remove 删除盘点明细
	 * @param $id 盘点单id 
	 * @author liaojianwen
	 * @date 2017-01-19
	 */
	public function saveInventory($head, $detail, $remove, $id)
	{
		if(empty($head)){
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'head is empty' );
		}
		if (empty ( $detail )) {
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'detail is empty' );
		}
		//清掉为空的元素
		foreach ($head as $k =>$hed){
			if(empty($hed)){
				unset($head[$k]);
			}
		}
		foreach ($detail as $k=> $det){
			foreach ($det as $j => $deet){
				if(empty($deet)){
					unset($detail[$k][$j]);
				}
			}
		}
		// 表头信息
		$tr = Yii::$app->db->beginTransaction();
		try{
			$head ['inventory_date'] = strtotime ( $head ['inventory_date'] );
			$cond_head = "inventory_id =:id";
			$param_head = [
					':id' => $id
			];
			$Iid = InventoryDAO::getInstance ()->ireplaceinto ( $head, $cond_head, $param_head, true );
			if (! $Iid) {
				$tr->rollBack();
				return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'save inventory_head failure' );
			}
			// 表单明细
// 			InventoryDetailDAO::getInstance()->iupdate(['delete_flag' => EnumOther::DELETED], "inventory_id =:did", [':did'=>$Iid]);// 先删除后没有删除的数据更新回来
			//删除的明细
			foreach ($remove as $move){
				$res_remove = InventoryDetailDAO::getInstance()->iupdate(['delete_flag'=>EnumOther::DELETED], "inventory_det_id = :det_id", [':det_id'=>$move['inventory_det_id']]);
				if(!$res_remove){
					$tr->rollBack();
					$this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'remove inventory_det_id:'+$move['inventory_det_id'] +'failed');
				}
			}
			foreach ( $detail as &$det ) {
				$det ['inventory_id'] = $Iid;
				$det ['delete_flag'] = EnumOther::NO_DELETE;
				$cond_det = "inventory_id = :id and inventory_det_id = :lid";
				$param_det = [
						':id' => $Iid,
						':lid' => isset($det ['inventory_det_id'])?$det['inventory_det_id']:0,
				];
				$res_det = InventoryDetailDAO::getInstance ()->ireplaceinto ( $det, $cond_det, $param_det, true );
				if (! $res_det) {
					$tr->rollBack();
					return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'save inventory_detail failure' );
				}
			}
			$tr->commit();
			return $this->handleApiFormat ( EnumOther::ACK_SUCCESS, '' );
		}catch (\Exception $e){
			$tr->rollBack();
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', $e->getMessage());
		}
	}
	
	/**
	 * @desc 盘点列表
	 * @param $pageInfo 页面信息
	 * @param $condition 查询条件
	 * @param $filter 过滤条件
	 * @author liaojianwen
	 */
	public function getInventorys ( $pageInfo, $condition, $filter)
	{
		if(empty($pageInfo)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','param is empty');
		}
		$result = InventoryDAO::getInstance()->getInventorys($condition, $filter, $pageInfo);
		if(empty($result)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','no data found');
		}
		return $this->handleApiFormat(EnumOther::ACK_SUCCESS,$result);
	}
	
	/**
	 * @desc  根据id获取盘点单明细
	 * @param $id 盘点单id
	 * @author liaojianwen
	 * @date 2017-01-19
	 */
	public function getInventoryDet($id)
	{
		if (! $id) {
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'param is empty' );
		}
		$fields = [
				'inventory_det_id',
				'd.inventory_id',
				'd.product_id',
				'p.product_name',
				'c.category_name',
				'd.lost_quantity',
				'd.quantity',
				'd.inventory_quantity',
				'd.quantity_unit',
				'u.unit_name',
				'd.price',
				'd.amount',
				'd.remark',
		];
		
		$joinArr = [
				[
						"product p",
						"p.product_id = d.product_id",
						'left'=>''
				],
				[
						"unit u",
						"u.unit_id = d.quantity_unit",
						'left'=>''
				],
				[
					    "category c",
					    "c.category_id = p.category_id",
					    "left" =>''
				]
		];
		$conditions = "d.inventory_id = :id and d.delete_flag = :dflag";
		$params = [
				':id' => $id,
				':dflag' => EnumOther::NO_DELETE,
		];
		$result = InventoryDetailDAO::getInstance()->iselect($fields, $conditions, $params, 'all',"inventory_det_id ASC", $joinArr,'d');
		if(empty($result)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','no data found');
		}
		return $this->handleApiFormat(EnumOther::ACK_SUCCESS, $result);
	}
	
	
	/**
	 * @desc 根据id 获取盘点编辑信息
	 * @param int $id //盘点单id
	 * @author liaojianwen
	 * @date 2017-01-19
	 */
	public function getInventoryInfo($id)
	{
		if(empty($id)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','param is empty');
		}
		$in_head = InventoryDAO::getInstance()->getInventoryHead($id);
		if(empty($in_head)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','head data found');
		}
		$in_det = InventoryDetailDAO::getInstance()->getInventoryDet($id);
		if(empty($in_det)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','detail data found');
		}
		$result['head'] = $in_head;
		$result['det'] = $in_det;
		return $this->handleApiFormat(EnumOther::ACK_SUCCESS,$result);
	}
	
	/**
	 * @desc 删除盘点单
	 * @author liaojianwen
	 * @date 2017-01-20
	 */
	public function delInventory($ids)
	{
		if(empty($ids)){
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'param is empty' );
		}
		$_ids = explode ( ',', $ids );
		
		$tT = Yii::$app->db->beginTransaction ();
		try {
			foreach ( $_ids as $id ) {
				//检查是否是存在盈亏单 如果有提示用户
				$fields = [
					'inventory_id'
				];
				$conditions ="inventory_id = :id";
				$params = [
					':id'=>$id,
				];
				$res_full = InventoryFullDAO::getInstance()->iselect($fields, $conditions, $params,'one');
				if($res_full){
					return $this->handleApiFormat(EnumOther::ACK_FAILURE, '','full order is exist');
				}
				
				$res_lost = InventoryLostDAO::getInstance()->iselect($fields, $conditions, $params,'one');
				if($res_lost){
					return $this->handleApiFormat(EnumOther::ACK_FAILURE, '','lost order is exist');
				}
				
				$res_inventory = InventoryDAO::getInstance ()->updateByPk ( $id, ['delete_flag' => EnumOther::DELETED] );
				if(!$res_inventory){
					$tT->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'del_inventory fail');
				}
				//inventory_detail
				$inventory_det = InventoryDetailDAO::getInstance()->iupdate(['delete_flag'=>EnumOther::DELETED], "inventory_id=:id", [':id'=>$id]);
				if(!$inventory_det){
					$tT->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','del_inventory_det fail');
				}
				$tT->commit();
				return $this->handleApiFormat(EnumOther::ACK_SUCCESS,'');
			}
		} catch ( \Exception $e ) {
			$tT->rollBack ();
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', $e->getMessage());
		}
	}
	
	/**
	 * @desc 确认盘点单
	 * @author liaojianwen
	 * @date 2016-11-25
	 */
	public function confirmInventory($id)
	{
		if (! $id) {
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'param is empty' );
		}
		$id = (int)$id;
		$tr = Yii::$app->db->beginTransaction ();
		try {
			$re_confirm = InventoryDAO::getInstance ()->updateByPk ( $id, [
					'confirm_flag' => EnumOther::CONFIRM
			] );
			if (! $re_confirm) {
				$tr->rollBack ();
				return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'confirm fail' );
			}
			//查询盘点单明细生成盈亏单
			$fields = [
					'h.inventory_id',
					'h.inventory_no',
					'd.product_id',
// 					'd.quantity',
					'd.inventory_det_id',
					'h.warehouse_id',
					'h.inventory_date',
					'd.quantity_unit',
					'd.lost_quantity',
					'd.price',
					'h.handle_man',
			];
			$conditions = "d.inventory_id =:id and d.delete_flag = :flag";
			$params = [
					':id' => $id,
					':flag' => EnumOther::NO_DELETE
			];
			$joinArray = [
					[
							'inventory h',
							"h.inventory_id = d.inventory_id"
					]
			];
			$inventory_det = InventoryDetailDAO::getInstance ()->iselect ( $fields, $conditions, $params, 'all', 'd.inventory_det_id ASC', $joinArray, 'd' );
			if (! $inventory_det) {
				$tr->rollBack ();
				return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'select det fail' );
			}
			// 出入库明细
			$full_header =[];
			$full_det =[];
			$lost_header = [];
			$lost_det = [];
			$full_amount  = 0;
			$lost_amount = 0;
			foreach ( $inventory_det as $det ) {
				//判断盘点数量 大于0生成盘盈单（出库） 小于0 生成盘亏单(入库)
				if($det['lost_quantity'] > 0){
					//生成盘盈单
					$full_header = array (
							'inventory_full_no' => EnumOriginType::INVENTORY_FULL. date('YmdHis'),
							'inventory_full_date' => $det ['inventory_date'],
							'inventory_id' => $det ['inventory_id'],
							'warehouse_id' => $det ['warehouse_id'],
							'handle_man'=> $det['handle_man'],
							'create_man'=>Yii::$app->user->id,
							'remark'=> EnumOther::INVENTORY_REMARK.$det['inventory_no'],
					);
					
					
					$column_det = array (
							'product_id' => $det ['product_id'],
							'quantity' => $det ['lost_quantity'],
							'quantity_unit'=> $det['quantity_unit'],
							'base_quantity'=> $det['lost_quantity'],
							'base_unit'=> $det['quantity_unit'],
							'inventory_det_id' => $det ['inventory_det_id'],
							'price'=> $det['price'],
							'amount'=> $det['price'] * $det['lost_quantity'],
					);
					$full_amount += $column_det['amount'];
					array_push($full_det, $column_det);
				} else if($det['lost_quantity'] < 0){
					//生成盘亏单
					$lost_header = array (
							'inventory_lost_no' => EnumOriginType::INVENTORY_LOST. date('YmdHis'),
							'inventory_lost_date' => $det ['inventory_date'],
							'inventory_id' => $det ['inventory_id'],
							'warehouse_id' => $det ['warehouse_id'],
							'handle_man'=> $det['handle_man'],
							'create_man'=>Yii::$app->user->id,
							'remark'=> EnumOther::INVENTORY_REMARK.$det['inventory_no'],
					);
						
						
					$column_det = array (
							'product_id' => $det ['product_id'],
							'quantity' => -$det ['lost_quantity'],//是负数
							'quantity_unit'=> $det['quantity_unit'],
							'base_quantity'=> -$det['lost_quantity'],
							'base_unit'=> $det['quantity_unit'],
							'inventory_det_id' => $det ['inventory_det_id'],
							'price'=> $det['price'],
							'amount'=> $det['price'] * (-$det['lost_quantity']),
					);
					$lost_amount +=$column_det['amount'];
					array_push($lost_det, $column_det);
					
				} else {
					//核算各个仓库是否与总仓数量相等
					$res_account = $this->AccountStock($det ['product_id']);
					if(!$res_account){
						$tr->rollBack();
						return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'accounting stock_pile quantity fail');
					}
					
					
				}
	
			}
			
			if($full_header){
				//生成盘盈单
				$full_header['total_amount'] = $full_amount;
				$ful_header = InventoryFullDAO::getInstance ()->iinsert ( $full_header, true );
				if (! $ful_header) {
					$tr->rollBack ();
					return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'insert inventory_full header failure' );
				}
				foreach ($full_det as &$full){
					$full['inventory_full_id'] = $ful_header;
					$res_det = InventoryFullDetailDAO::getInstance ()->iinsert ( $full, true );
					if (! $res_det) {
						$tr->rollBack ();
						return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'insert inventory_full detail failure' );
					}
					
				}
				
			}
			if($lost_header){
					// 生成盘亏单
				$lost_header['total_amount'] = $lost_amount;
				$res_header = InventoryLostDAO::getInstance ()->iinsert ( $lost_header, true );
				if (! $res_header) {
					$tr->rollBack ();
					return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'insert inventory_lost header failure' );
				}
				foreach($lost_det as &$lost){
					$lost['inventory_lost_id'] = $res_header;
					$res_det = InventoryLostDetailDAO::getInstance ()->iinsert ( $lost, true );
					if (! $res_det) {
						$tr->rollBack ();
						return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'insert inventory_lost detail failure' );
					}
				}
			}
			$tr->commit();
			return $this->handleApiFormat(EnumOther::ACK_SUCCESS,'');
		} catch ( \Exception $e ) {
			$tr->rollBack ();
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', $e->getMessage());
		}
	}
	
	/**
	 * @desc 核算各个仓库商品数量
	 * @author liaojianwen
	 * @date 2018-04-17
	 */
	private function AccountStock($goods_id)
	{
		try{
			$stock_res = StockPileDAO::getInstance()->getAccountStock($goods_id);
			if(empty($stock_res)){
				return false;
			}
			$goods_select = ProductDAO::getInstance()->iselect("quantity", "product_id = :gid", [
					':gid' => $goods_id
			],'one');
			if($goods_select['quantity'] != $stock_res['quantity']){
				$res = ProductDAO::getInstance()->iupdate(['quantity'=>$stock_res['quantity']], "product_id = :gid", [
						':gid' => $goods_id
				]);
				if(!$res){
					return false;
				}
				$message = 'stock_quantity = '.$stock_res['quantity'] .' , product_quantity = '.$goods_select['quantity'] .', now_quantity = '.$stock_res['quantity'];
				Yii::trace($message,'accountStock');
			}
			return true;
		} catch(\Exception $e){
			return false;
		}
	}
	
	/**
	 * @desc 保存盘盈单
	 * @param [] $head 盘点单单头
	 * @param [] $detail 盘点单明细
	 * @param [] $remove 删除盘点明细
	 * @param $id 盘点单id
	 * @author liaojianwen
	 * @date 2017-02-05
	 */
	public function saveInventoryFull($head, $detail, $remove,$id)
	{
		if(empty($head)){
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'head is empty' );
		}
		if (empty ( $detail )) {
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'detail is empty' );
		}
		//清掉为空的元素
		foreach ($head as $k =>$hed){
			if(empty($hed)){
				unset($head[$k]);
			}
		}
		foreach ($detail as $k=> $det){
			foreach ($det as $j => $deet){
				if(empty($deet)){
					unset($detail[$k][$j]);
				}
			}
		}
		// 表头信息
		$tr = Yii::$app->db->beginTransaction();
		try{
			$head ['inventory_full_date'] = strtotime ( $head ['inventory_full_date'] );
			$cond_head = "inventory_full_id =:id";
			$param_head = [
					':id' => $id
			];
			$Iid = InventoryFullDAO::getInstance ()->ireplaceinto ( $head, $cond_head, $param_head, true );
			if (! $Iid) {
				$tr->rollBack();
				return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'save inventory_full_head failure' );
			}
			// 表单明细
// 			InventoryFullDetailDAO::getInstance()->iupdate(['delete_flag' => EnumOther::DELETED], "inventory_full_id =:did", [':did'=>$Iid]);// 先删除后没有删除的数据更新回来
			//删除的明细
			foreach ($remove as $move){
				$res_remove = InventoryFullDetailDAO::getInstance()->iupdate(['delete_flag'=>EnumOther::DELETED], "inventory_full_det_id = :det_id", [':det_id'=>$move['inventory_full_det_id']]);
				if(!$res_remove){
					$tr->rollBack();
					$this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'remove inventory_full_det_id:'+$move['inventory_full_det_id'] +'failed');
				}
			}
			foreach ( $detail as &$det ) {
				$det ['inventory_full_id'] = $Iid;
				$det ['delete_flag'] = EnumOther::NO_DELETE;
				$cond_det = "inventory_full_id = :id and inventory_full_det_id = :lid";
				$param_det = [
						':id' => $Iid,
						':lid' => isset($det ['inventory_full_det_id'])?$det['inventory_full_det_id']:0,
				];
				$res_det = InventoryFullDetailDAO::getInstance ()->ireplaceinto ( $det, $cond_det, $param_det, true );
				if (! $res_det) {
					$tr->rollBack();
					return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'save inventory_full_detail failure' );
				}
			}
			$tr->commit();
			return $this->handleApiFormat ( EnumOther::ACK_SUCCESS, '' );
		}catch (\Exception $e){
			$tr->rollBack();
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', $e->getMessage());
		}
	}
	
	/**
	 * @desc 盘盈列表
	 * @param $pageInfo 页面信息
	 * @param $condition 查询条件
	 * @param $filter 过滤条件
	 * @author liaojianwen
	 * @date 2017-02-05
	 */
	public function getInventoryFull ( $pageInfo, $condition, $filter)
	{
		if(empty($pageInfo)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','param is empty');
		}
		$result = InventoryFullDAO::getInstance()->getInventoryFull($condition, $filter, $pageInfo);
		if(empty($result)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','no data found');
		}
		return $this->handleApiFormat(EnumOther::ACK_SUCCESS,$result);
	}
	
	/**
	 * @desc 编辑页面初始化信息
	 * @param $id int 盘盈单id 
	 * @author liaojianwen
	 * @date 2017-02-05
	 */
	public function getInventoryFullInfo($id)
	{
		if(empty($id)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','param is empty');
		}
		$in_head = InventoryFullDAO::getInstance()->getInventoryFullHead($id);
		if(empty($in_head)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','head data found');
		}
		$in_det = InventoryFullDetailDAO::getInstance()->getInventoryFullDet($id);
		if(empty($in_det)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','detail data found');
		}
		$result['head'] = $in_head;
		$result['det'] = $in_det;
		return $this->handleApiFormat(EnumOther::ACK_SUCCESS,$result);
	}
	
	/**
	 * @desc 根据盘盈单号查询盘盈单明细
	 * @author liaojianwen
	 * @date 2017-02-05
	 */
	public function getInventoryFullDet($id)
	{
		if (! $id) {
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'param is empty' );
		}
		$fields = [
				'inventory_full_det_id',
				'd.inventory_full_id',
				'd.product_id',
				'p.product_name',
				'p.product_sn',
				'd.quantity',
				'd.quantity_unit',
				'u.unit_name',
				'd.price',
				'd.amount',
				'd.remark',
		];
		
		$joinArr = [
				[
						"product p",
						"p.product_id = d.product_id"
				],
				[
						"unit u",
						"u.unit_id = d.quantity_unit"
				]
		];
		$conditions = "d.inventory_full_id = :id and d.delete_flag = :dflag";
		$params = [
				':id' => $id,
				':dflag' => EnumOther::NO_DELETE,
		];
		$result = InventoryFullDetailDAO::getInstance()->iselect($fields, $conditions, $params, 'all',"inventory_full_det_id ASC", $joinArr,'d');
		if(empty($result)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','no data found');
		}
		return $this->handleApiFormat(EnumOther::ACK_SUCCESS, $result);
	}
	
	/**
	 * @desc 删除盘盈单（出库操作）
	 * @author liaojianwen
	 * @date 2017-02-06
	 */
	public function delInventoryFull($ids)
	{
		if(empty($ids)){
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'param is empty' );
		}
		$_ids = explode ( ',', $ids );
	
		$tT = Yii::$app->db->beginTransaction ();
		try {
			foreach ( $_ids as $id ) {
				$res_inventory = InventoryFullDAO::getInstance ()->updateByPk ( $id, ['delete_flag' => EnumOther::DELETED] );
				if(!$res_inventory){
					$tT->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'del_inventory_full fail');
				}
				//instore_detail
				$inventory_det = InventoryFullDetailDAO::getInstance()->iupdate(['delete_flag'=>EnumOther::DELETED], "inventory_full_id=:id", [':id'=>$id]);
				if(!$inventory_det){
					$tT->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','del_inventory_full_det fail');
				}
				//更新product_quantity
				$fields = [
						't.goods_id',
						't.quantity',
						't.transaction_id',
						'd.quantity_unit',
						'i.warehouse_id',
						'i.inventory_full_no',
						't.origin_type',
						'd.quantity_unit',
						'd.inventory_full_det_id'
				];
				$conditions = "t.delete_flag = :flag";
				$params = [
						':flag'=>EnumOther::NO_DELETE,
				];
				$joinArray = [
						[
								'inventory_full i',
								'i.inventory_full_no = t.origin_id and i.inventory_full_id = '.$id,
								'right'=>'',
						],
						[
								'inventory_full_detail d',
								'd.inventory_full_det_id = t.origin_line_id',
								'left'=>''
						]
				];
				$trans_select = TransactionDAO::getInstance()->iselect($fields, $conditions, $params,'all',"t.create_time ASC",$joinArray,'t');
				if (! empty ( $trans_select )) {
					// 已确认的入库单才有transtions,减库存
					foreach ( $trans_select as $trans ) {
						//记录更新product 前的quantity
						$PRODUCT = ProductDAO::getInstance()->iselect("quantity", "product_id = :pid", [':pid'=>$trans['goods_id']],'one');
						//product 更新数量(盘亏单相当于入库)
						$pro_minus = ProductDAO::getInstance ()->updateAllCounters ( [
								'quantity' => -$trans ['quantity'],
						], "product_id =:id", [
								':id' => $trans ['goods_id']
						] );
							
						if (! $pro_minus) {
							$tr->rollBack ();
							return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'update product quantity failure' );
						}
	
						//product_update_log 商品更新记录
						$_order_type = Utility::getArrayValue(EnumOriginType::$origin_type, $trans['origin_type']);
	
						$log_columns = [
								'product_id' => $trans ['goods_id'],
								'update_num' => $trans ['quantity'],
								'num_unit' => $trans['quantity_unit'],
								'origin_id' => $id,
								'origin_no' => $trans['inventory_full_no'],
								'origin_line_id'=> $trans['inventory_full_det_id'],
								'origin_type'=> $trans['origin_type'],
								'update_time'=> strtotime(date('Y-m-d')),
								'flag'=> EnumOther::OUT_FLAG,
								'initial_num'=> $PRODUCT['quantity'],//上期数量
								'remark'=> $_order_type . EnumOther::MINUS.',盘盈单删除',
								'warehouse_id' => $trans['warehouse_id'],
								'create_man' => Yii::$app->user->id,
						];
						$res_log = ProductUpdateLogDAO::getInstance()->iinsert($log_columns, true);
						if(! $res_log){
							$tr->rollBack();
							return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'product update log failure');
						}
	
						//删除transaction 数据
						$columns = [
								'delete_flag'=>EnumOther::DELETED,
						];
						$conditions = "transaction_id = :tid";
						$params = [
								':tid'=>$trans['transaction_id'],
						];
						$trans_update = TransactionDAO::getInstance()->iupdate($columns, $conditions, $params);
	
						if(empty($trans_update)){
							$tT->rollBack();
							return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','tansaction del fail');
						}
						// 更新stock_file 分仓表信息
						$stock_minus = StockPileDAO::getInstance ()->updateAllCounters ( [
								'quantity' => - $trans ['quantity']
						], "warehouse_id =:wid and product_id=:pid and delete_flag =:flag", [
								':wid' => $trans ['warehouse_id'],
								':pid' => $trans ['goods_id'],
								':flag' => EnumOther::NO_DELETE
						] );
						if(! $stock_minus){
							$tr->rollBack ();
							return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'update stock pile quantity failure');
						}
					}
				}
			}
	
			$tT->commit();
			return $this->handleApiFormat(EnumOther::ACK_SUCCESS,'');
		} catch ( \Exception $e ) {
			$tT->rollBack ();
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', $e->getMessage());
		}
	}
	
	
	/**
	 * @desc 确认盘盈单（入库操作）
	 * @author liaojianwen
	 * @date 2017-02-06
	 */
	public function confirmInventoryFull($id)
	{
		if (! $id) {
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'param is empty' );
		}
		$id = (int)$id;
		$tr = Yii::$app->db->beginTransaction ();
		try {
			$re_confirm = InventoryFullDAO::getInstance ()->updateByPk ( $id, [
					'confirm_flag' => EnumOther::CONFIRM
			] );
			if (! $re_confirm) {
				$tr->rollBack ();
				return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'confirm fail' );
			}
			$fields = [
					'h.inventory_full_no',
					'd.product_id',
					'd.quantity',
					// 					'h.inventory_full_type',
					'd.inventory_full_det_id',
					'h.warehouse_id',
					'h.inventory_full_date',
					'd.quantity_unit',
					'd.base_quantity',
					'd.base_unit',
			];
			$conditions = "d.inventory_full_id =:id and d.delete_flag = :flag";
			$params = [
					':id' => $id,
					':flag' => EnumOther::NO_DELETE
			];
			$joinArray = [
					[
							'inventory_full h',
							"h.inventory_full_id = d.inventory_full_id"
					]
			];
			$inventory_full_det = InventoryFullDetailDAO::getInstance ()->iselect ( $fields, $conditions, $params, 'all', 'd.inventory_full_det_id ASC', $joinArray, 'd' );
			if (! $inventory_full_det) {
				$tr->rollBack ();
				return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'select det fail' );
			}
			// 入库明细
			foreach ( $inventory_full_det as $det ) {
				$PRODUCT = ProductDAO::getInstance()->iselect(["price","quantity"], "product_id = :pid", [':pid'=>$det['product_id']],'one');
				if(isset($PRODUCT['price'])){
					$price = $PRODUCT['price'];
				} else {
					$price = 0;
				}
				
				$column_trans = array (
						'goods_id' => $det ['product_id'],
						'quantity' => $det ['base_quantity'],
						'quantity_unit'=> $det['base_unit'],
						'origin_type' => EnumOriginType::origin_py_out,
						'origin_id' => $det ['inventory_full_no'],
						'origin_line_id' => $det ['inventory_full_det_id'], // 原单序号
						'origin_time'=>$det['inventory_full_date'],
						'warehouse_id' => $det ['warehouse_id'],
						'init_num' => $PRODUCT['quantity'],//上期数量
						'flag' => EnumOther::IN_FLAG
						
				);
	
				$res_trans = TransactionDAO::getInstance ()->iinsert ( $column_trans, true );
				if (! $res_trans) {
					$tr->rollBack ();
					return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'save transaction failure' );
				}
	
	

				// 更新product quantity 加库存
				$WAREHOUSE = WarehouseDAO::getInstance()->iselect("is_scrapped,warehouse_name", "warehouse_id =:wid", [':wid'=>$det['warehouse_id']],'one');
				if(isset($WAREHOUSE['is_scrapped'])){
					if($WAREHOUSE['is_scrapped'] != '1'){//不是报废单
						$pro_select = ProductDAO::getInstance ()->updateAllCounters ( [
								'quantity' => $det['base_quantity'],
								'amount' => $det['base_quantity'] * $price
						], "product_id =:id", [
								':id' => $det ['product_id']
						] );
						if (! $pro_select) {
							$tr->rollBack ();
							return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'update product quantity failure' );
						}
					}
				} else {
					$tr->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','select scrapped failed');
				}
	
				//product_update_log 商品更新记录
				$_order_type = Utility::getArrayValue(EnumOriginType::$origin_type, EnumOriginType::origin_py_out);
	
				$log_columns = [
						'product_id' => $det ['product_id'],
						'update_num' => $det['base_quantity'],
						'num_unit' => $det['base_unit'],
						'origin_id' => $id,
						'origin_no' => $det['inventory_full_no'],
						'origin_line_id'=> $det['inventory_full_det_id'],
						'origin_type'=> EnumOriginType::origin_py_out,
						'update_time'=>strtotime(date('Y-m-d')),
						'flag'=> EnumOther::IN_FLAG,
						'initial_num'=> $PRODUCT['quantity'],//上期数量
						'remark'=> $_order_type .($WAREHOUSE['warehouse_name']?:''). EnumOther::PLUS,
						'warehouse_id' => $det['warehouse_id'],
						'create_man' => Yii::$app->user->id,
				];
				$res_log = ProductUpdateLogDAO::getInstance()->iinsert($log_columns, true);
				if(! $res_log){
					$tr->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'product update log failure');
				}
					
				// 分仓列表数据的插入或者更新--start
				$stock_conditions = "warehouse_id =:wid and product_id=:pid and delete_flag =:flag";
				$stock_params = [
						':wid' => $det ['warehouse_id'],
						':pid' => $det ['product_id'],
						':flag' => EnumOther::NO_DELETE
				];
				$stock_select = StockPileDAO::getInstance ()->iselect ( "stock_pile_id", $stock_conditions, $stock_params, 'one' );
				if (! $stock_select) {
					// 没有数据，插入新数据
					$stock_columns = [
							'warehouse_id' => $det ['warehouse_id'],
							'product_id' => $det ['product_id'],
							'quantity' => $det['base_quantity'],
							'quantity_unit' => $det ['base_unit']
					];
					$stock_insert = StockPileDAO::getInstance ()->iinsert ( $stock_columns, true );
					if (! $stock_insert) {
						$tr->rollBack ();
						return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'select stock pile failure' );
					}
				} else {
					// 有数据，更新数据
					$stock_update = StockPileDAO::getInstance ()->updateAllCounters ( [
							'quantity' => $det['base_quantity']
					], $stock_conditions, $stock_params );
					if (! $stock_update) {
						$tr->rollBack ();
						return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'update stock pile failure' );
					}
				}
				//分仓 --end
				
				//核算各个仓库中商品数量
				$res_account = $this->AccountStock($det ['product_id']);
				if(!$res_account){
					$tr->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'accounting stock_pile quantity fail');
				}
	
			}
			$tr->commit();
			return $this->handleApiFormat(EnumOther::ACK_SUCCESS,'');
		} catch ( \Exception $e ) {
			$tr->rollBack ();
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'',$e->getMessage());
		}
	}
	
	
	
	
	/**
	 * @desc 保存盘亏单
	 * @param [] $head 盘点单单头
	 * @param [] $detail 盘点单明细
	 * @param [] $remove 删除盘点明细
	 * @param $id 盘点单id
	 * @author liaojianwen
	 * @date 2017-02-06
	 */
	public function saveInventoryLost ( $head, $detail, $remove, $id )
	{
		if(empty($head)){
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'head is empty' );
		}
		if (empty ( $detail )) {
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'detail is empty' );
		}
		//清掉为空的元素
		foreach ($head as $k =>$hed){
			if(empty($hed)){
				unset($head[$k]);
			}
		}
		foreach ($detail as $k=> $det){
			foreach ($det as $j => $deet){
				if(empty($deet)){
					unset($detail[$k][$j]);
				}
			}
		}
		
		// 表头信息
		$tr = Yii::$app->db->beginTransaction();
		try{
			$head ['inventory_lost_date'] = strtotime ( $head ['inventory_lost_date'] );
			$cond_head = "inventory_lost_id =:id";
			$param_head = [
					':id' => $id
			];
			$Iid = InventoryLostDAO::getInstance ()->ireplaceinto ( $head, $cond_head, $param_head, true );
			if (! $Iid) {
				$tr->rollBack();
				return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'save inventory_lost_head failure' );
			}
			// 表单明细
// 			InventoryLostDetailDAO::getInstance()->iupdate(['delete_flag' => EnumOther::DELETED], "inventory_lost_id =:did", [':did'=>$Iid]);// 先删除后没有删除的数据更新回来
			//删除的明细
			foreach ($remove as $move){
				$res_remove = InventoryLostDetailDAO::getInstance()->iupdate(['delete_flag'=>EnumOther::DELETED], "inventory_lost_det_id = :det_id", [':det_id'=>$move['inventory_lost_det_id']]);
				if(!$res_remove){
					$tr->rollBack();
					$this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'remove inventory_lost_det_id:'+$move['inventory_lost_det_id'] +'failed');
				}
			}
			foreach ( $detail as &$det ) {
				//检查是否是负库存出库
				$res_stock = StockPileDAO::getInstance()->checkQty($head['warehouse_id'],$det['product_id']);
				if(isset($res_stock['quantity']) && isset($res_stock['quantity_unit'])){
					if($det['base_unit'] == $res_stock['quantity_unit']){
						if($det['base_quantity'] > $res_stock['quantity']){
							$tr->rollBack();
							return $this->handleApiFormat(EnumOther::ACK_FAILURE,'', $res_stock['product_name'] . EnumOther::OVERQUANTITY );
						}
					} else {
						$tr->rollBack();
						return $this->handleApiFormat(EnumOther::ACK_FAILURE,'', 'lost.base_unit != stock_pile.quantity_unit');
					}
				} else {
					$tr->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE,'', 'check stock_pile quantity failed');
				}
				
				$det ['inventory_lost_id'] = $Iid;
				$det ['delete_flag'] = EnumOther::NO_DELETE;
				//添加 成本 --start
				$PRODUCT = ProductDAO::getInstance()->iselect("price", "product_id =:pid", [':pid' => $det['product_id']],'one');
				if(empty($PRODUCT)){
					$tr->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'product is null');
				}
				$det['cost_price'] = $PRODUCT['price'];
				$det['cost_amount'] = round(($PRODUCT['price'] * $det['quantity']),2);
				//---end
				
				
				$cond_det = "inventory_lost_id = :id and inventory_lost_det_id = :lid";
				$param_det = [
						':id' => $Iid,
						':lid' => isset($det ['inventory_lost_det_id'])?$det['inventory_lost_det_id']:0,
				];
				$res_det = InventoryLostDetailDAO::getInstance ()->ireplaceinto ( $det, $cond_det, $param_det, true );
				if (! $res_det) {
					$tr->rollBack();
					return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'save inventory_lost_detail failure' );
				}
			}
			$tr->commit();
			return $this->handleApiFormat ( EnumOther::ACK_SUCCESS, '' );
		}catch (\Exception $e){
			$tr->rollBack();
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', $e->getMessage());
		}
	}
	
	/**
	 * @desc 上传报损产品图片
	 * @author lizichuan
	 * @date 2018-6-14
	 */
	public function uploadInventoryLostImage()
	{
		$product_img = (new FileUploader())->upload('upload_img', '|png|jpg|jpeg|gif|bmp|');
		if ($product_img) {
			$thumb_img = (new ImageHelper())->thumb($product_img, dirname($product_img).'/thumb/', 0, 300);
			if ($thumb_img) {
				$product_img = $thumb_img;
			}
		}
		if ($product_img) {
			return $this->handleApiFormat ( EnumOther::ACK_SUCCESS, ['product_img'=>$product_img] );
		}
		else {
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', '上传图片失败' );
		}
	}
	
	/**
	 * @desc 盘亏列表
	 * @param $pageInfo 页面信息
	 * @param $condition 查询条件
	 * @param $filter 过滤条件
	 * @author liaojianwen
	 * @date 2017-02-06
	 */
	public function getInventoryLost ( $pageInfo, $condition, $filter)
	{
		if(empty($pageInfo)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','param is empty');
		}
		$result = InventoryLostDAO::getInstance()->getInventoryLost($condition, $filter, $pageInfo);
		if(empty($result)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','no data found');
		}
		return $this->handleApiFormat(EnumOther::ACK_SUCCESS,$result);
	}
	
	/**
	 * @desc 编辑页面初始化信息
	 * @param $id int 盘亏单id
	 * @author liaojianwen
	 * @date 2017-02-06
	 */
	public function getInventoryLostInfo($id)
	{
		if(empty($id)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','param is empty');
		}
		$in_head = InventoryLostDAO::getInstance()->getInventoryLostHead($id);
		if(empty($in_head)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','head data found');
		}
		$in_det = InventoryLostDetailDAO::getInstance()->getInventoryLostDet($id);
		if(empty($in_det)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','detail data found');
		}
		$result['head'] = $in_head;
		$result['det'] = $in_det;
		return $this->handleApiFormat(EnumOther::ACK_SUCCESS,$result);
	}
	
	/**
	 * @desc 根据盘亏单号查询盘亏单明细
	 * @author liaojianwen
	 * @date 2017-02-06
	 */
	public function getInventoryLostDet($id)
	{
		if (! $id) {
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'param is empty' );
		}
		$fields = [
				'inventory_lost_det_id',
				'd.inventory_lost_id',
				'd.product_id',
				'p.product_name',
				'p.product_sn',
				'd.quantity',
				'd.quantity_unit',
				'u.unit_name',
				'd.price',
				'd.amount',
				'd.remark',
		];
	
		$joinArr = [
				[
						"product p",
						"p.product_id = d.product_id"
				],
				[
						"unit u",
						"u.unit_id = d.quantity_unit"
				]
		];
		$conditions = "d.inventory_lost_id = :id and d.delete_flag = :dflag";
		$params = [
				':id' => $id,
				':dflag' => EnumOther::NO_DELETE,
		];
		$result = InventoryLostDetailDAO::getInstance()->iselect($fields, $conditions, $params, 'all',"inventory_lost_det_id ASC", $joinArr,'d');
		if(empty($result)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','no data found');
		}
		return $this->handleApiFormat(EnumOther::ACK_SUCCESS, $result);
	}
	
	/**
	 * @desc 删除盘亏单
	 * @author liaojianwen
	 * @date 2017-02-05
	 */
	public function delInventoryLost($ids)
	{
		if(empty($ids)){
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'param is empty' );
		}
		$_ids = explode ( ',', $ids );
	
		$tT = Yii::$app->db->beginTransaction ();
		try {
			foreach ( $_ids as $id ) {
				$res_inventory = InventoryLostDAO::getInstance ()->updateByPk ( $id, ['delete_flag' => EnumOther::DELETED] );
				if(!$res_inventory){
					$tT->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'del_inventory_lost fail');
				}
				//instore_detail
				$inventory_det = InventoryLostDetailDAO::getInstance()->iupdate(['delete_flag'=>EnumOther::DELETED], "inventory_lost_id=:id", [':id'=>$id]);
				if(!$inventory_det){
					$tT->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','del_inventory_lost_det fail');
				}
				//更新product_quantity
				$fields = [
						't.goods_id',
						't.quantity',
						't.transaction_id',
						'd.quantity_unit',
						'i.warehouse_id',
						'i.inventory_lost_no',
						't.origin_type',
						'd.quantity_unit',
						'd.inventory_lost_det_id'
				];
				$conditions = "t.delete_flag = :flag";
				$params = [
						':flag'=>EnumOther::NO_DELETE,
				];
				$joinArray = [
						[
								'inventory_lost i',
								'i.inventory_lost_no = t.origin_id and i.inventory_lost_id = '.$id,
								'right'=>'',
						],
						[
								'inventory_lost_detail d',
								'd.inventory_lost_det_id = t.origin_line_id',
								'left'=>''
						]
				];
				$trans_select = TransactionDAO::getInstance()->iselect($fields, $conditions, $params,'all',"t.create_time ASC",$joinArray,'t');
				if (! empty ( $trans_select )) {
					// 已确认的入库单才有transtions,减库存
					foreach ( $trans_select as $trans ) {
						//记录更新product 前的quantity
						$PRODUCT = ProductDAO::getInstance()->iselect("quantity", "product_id = :pid", [':pid'=>$trans['goods_id']],'one');
						//product 更新数量
						$pro_minus = ProductDAO::getInstance ()->updateAllCounters ( [
								'quantity' => $trans ['quantity'],
						], "product_id =:id", [
								':id' => $trans ['goods_id']
						] );
							
						if (! $pro_minus) {
							$tr->rollBack ();
							return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'update product quantity failure' );
						}
	
						//product_update_log 商品更新记录
						$_order_type = Utility::getArrayValue(EnumOriginType::$origin_type, $trans['origin_type']);
	
						$log_columns = [
								'product_id' => $trans ['goods_id'],
								'update_num' => $trans ['quantity'],
								'num_unit' => $trans['quantity_unit'],
								'origin_id' => $id,
								'origin_no' => $trans['inventory_lost_no'],
								'origin_line_id'=> $trans['inventory_lost_det_id'],
								'origin_type'=> $trans['origin_type'],
								'update_time'=> strtotime(date('Y-m-d')),
								'flag'=> EnumOther::IN_FLAG,
								'initial_num'=> $PRODUCT['quantity'],//上期数量
								'remark'=> $_order_type . EnumOther::PLUS.',盘亏单删除',
								'warehouse_id' => $trans['warehouse_id'],
								'create_man' => Yii::$app->user->id,
						];
						$res_log = ProductUpdateLogDAO::getInstance()->iinsert($log_columns, true);
						if(! $res_log){
							$tr->rollBack();
							return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'product update log failure');
						}
	
						//删除transaction 数据
						$columns = [
								'delete_flag'=>EnumOther::DELETED,
						];
						$conditions = "transaction_id = :tid";
						$params = [
								':tid'=>$trans['transaction_id'],
						];
						$trans_update = TransactionDAO::getInstance()->iupdate($columns, $conditions, $params);
	
						if(empty($trans_update)){
							$tT->rollBack();
							return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','tansaction del fail');
						}
						// 更新stock_file 分仓表信息
						$stock_minus = StockPileDAO::getInstance ()->updateAllCounters ( [
								'quantity' => $trans ['quantity']
						], "warehouse_id =:wid and product_id=:pid and delete_flag =:flag", [
								':wid' => $trans ['warehouse_id'],
								':pid' => $trans ['goods_id'],
								':flag' => EnumOther::NO_DELETE
						] );
						if(! $stock_minus){
							$tr->rollBack ();
							return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'update stock pile quantity failure');
						}
					}
				}
			}
				
			$tT->commit();
			return $this->handleApiFormat(EnumOther::ACK_SUCCESS,'');
		} catch ( \Exception $e ) {
			$tT->rollBack ();
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', $e->getMessage());
		}
	}
	
	/**
	 * @desc 确认盘亏单（出库）
	 * @author liaojianwen
	 * @date 2017-02-05
	 */
	public function confirmInventoryLost($id)
	{
		if (! $id) {
			return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'param is empty' );
		}
		$id = (int)$id;
		$tr = Yii::$app->db->beginTransaction ();
		try {
			$re_confirm = InventoryLostDAO::getInstance ()->updateByPk ( $id, [
					'confirm_flag' => EnumOther::CONFIRM
			] );
			if (! $re_confirm) {
				$tr->rollBack ();
				return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'confirm fail' );
			}
			$fields = [
					'h.inventory_lost_id',
					'h.inventory_lost_no',
					'd.product_id',
					'd.quantity',
					// 					'h.inventory_lost_type',
					'd.inventory_lost_det_id',
					'h.warehouse_id',
					'h.inventory_lost_date',
					'd.quantity_unit',
					'd.base_quantity',
					'd.base_unit',
					's.quantity squantity',
					'd.base_price',
					'd.amount',
					'd.cost_price',
					'd.cost_amount'
			];
			$conditions = "d.inventory_lost_id =:id and d.delete_flag = :flag";
			$params = [
					':id' => $id,
					':flag' => EnumOther::NO_DELETE
			];
			$joinArray = [
					[
							'inventory_lost h',
							"h.inventory_lost_id = d.inventory_lost_id"
					],
					[
							'stock_pile s',
							's.product_id = d.product_id and s.warehouse_id = h.warehouse_id'
					]
			];
			$inventory_lost_det = InventoryLostDetailDAO::getInstance ()->iselect ( $fields, $conditions, $params, 'all', 'd.inventory_lost_det_id ASC', $joinArray, 'd' );
			if (! $inventory_lost_det) {
				$tr->rollBack ();
				return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'select det fail' );
			}
			// 出库明细
			foreach ( $inventory_lost_det as $det ) {
				$PRODUCT = ProductDAO::getInstance()->iselect(["price","quantity","product_name"], "product_id = :pid", [':pid'=>$det['product_id']],'one');
				if(isset($PRODUCT['price'])){
					$price = $PRODUCT['price'];
				} else {
					$price = 0;
				}
				
				if($det['base_quantity'] > $det['squantity']){
					$tr->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','overflow quantity');
				}
				$column_trans = array (
						'goods_id' => $det ['product_id'],
						'quantity' => $det ['base_quantity'],
						'quantity_unit'=> $det['base_unit'],
						'origin_type' => EnumOriginType::origin_pk_in,
						'origin_id' => $det ['inventory_lost_no'],
						'origin_line_id' => $det ['inventory_lost_det_id'], // 原单序号
						'origin_time'=>$det['inventory_lost_date'],
						'warehouse_id' => $det ['warehouse_id'],
						'init_num' => $PRODUCT['quantity'],//上期数量
						'flag' => EnumOther::OUT_FLAG
				);
	
				$res_trans = TransactionDAO::getInstance ()->iinsert ( $column_trans, true );
				if (! $res_trans) {
					$tr->rollBack ();
					return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'save transaction failure' );
				}
	
	

				// 更新product quantity 减库存
				$WAREHOUSE = WarehouseDAO::getInstance()->iselect("is_scrapped,warehouse_name", "warehouse_id =:wid", [':wid'=>$det['warehouse_id']],'one');
				if(isset($WAREHOUSE['is_scrapped'])){
					if($WAREHOUSE['is_scrapped'] != '1'){//不是报废单
						$pro_select = ProductDAO::getInstance ()->updateAllCounters ( [
								'quantity' => - $det ['base_quantity'],
								'amount' => -($det['base_quantity'] * $price)
						], "product_id =:id", [
								':id' => $det ['product_id']
						] );
						if (! $pro_select) {
							$tr->rollBack ();
							return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'update product quantity failure' );
						}
					}
				} else {
					$tr->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE,'','select scrapped failed');
				}
	
				// price_transaction
				$price_trans = [
						'product_id' => $det ['product_id'],
						'quantity' => $det ['base_quantity'],
						'quantity_unit' => $det ['base_unit'],
						'price' => $det ['base_price'],
						'amount' => $det ['amount'],
						'origin_type' => EnumOriginType::origin_pk_in,
						'origin_id' => $det ['inventory_lost_id'],
						'origin_no' => $det ['inventory_lost_no'],
						'origin_line_id' => $det ['inventory_lost_det_id'], // 原单序号
						'origin_time' => $det ['inventory_lost_date'],
						'warehouse_id' => $det ['warehouse_id'], // 调出仓库
						'cost_price' => $det ['cost_price'],
						'cost_amount' => $det ['cost_amount'],
				];
				$price_res = PriceTransactionDAO::getInstance()->iinsert($price_trans, true);
				if(! $price_res){
					$tr->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'save price transaction failed');
				}
				//---end
				
				//product_update_log 商品更新记录
				$_order_type = Utility::getArrayValue(EnumOriginType::$origin_type, EnumOriginType::origin_pk_in);
	
				$log_columns = [
						'product_id' => $det ['product_id'],
						'update_num' => $det ['base_quantity'],
						'num_unit' => $det['base_unit'],
						'origin_id' => $id,
						'origin_no' => $det['inventory_lost_no'],
						'origin_line_id'=> $det['inventory_lost_det_id'],
						'origin_type'=> EnumOriginType::origin_pk_in,
						'update_time'=>strtotime(date('Y-m-d')),
						'flag'=> EnumOther::OUT_FLAG,
						'initial_num'=> $PRODUCT['quantity'],//上期数量
						'remark'=> $_order_type .($WAREHOUSE['warehouse_name']?:''). EnumOther::MINUS,
						'warehouse_id' => $det['warehouse_id'],
						'create_man' => Yii::$app->user->id,
				];
				$res_log = ProductUpdateLogDAO::getInstance()->iinsert($log_columns, true);
				if(! $res_log){
					$tr->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'product update log failure');
				}
	
	
				//分仓列表数据的插入或者更新--start
				$stock_conditions = "warehouse_id =:wid and product_id=:pid and delete_flag =:flag";
				$stock_params = [
						':wid'=>$det['warehouse_id'],
						':pid'=>$det['product_id'],
						':flag'=> EnumOther::NO_DELETE,
				];
				$stock_select = StockPileDAO::getInstance()->iselect("stock_pile_id", $stock_conditions, $stock_params,'one');
				if(! $stock_select){
					//没有数据，插入新数据
					// 					$stock_columns = [
					// 							'warehouse_id'=> $det['warehouse_id'],
					// 							'product_id'=> $det['goods_id'],
					// 							'quantity'=> $det['quantity'],
					// 							'quantity_unit'=> $det['unit'],
					// 					];
					// 					$stock_insert = StockPileDAO::getInstance()->iinsert($stock_columns, true);
					// 					if(! $stock_insert){
					$tr->rollBack ();
					return $this->handleApiFormat ( EnumOther::ACK_FAILURE, '', 'select stock pile failure' );
					// 					}
				} else {
					//有数据，更新数据
					$stock_update = StockPileDAO::getInstance()->updateAllCounters(['quantity'=> -$det['base_quantity']], $stock_conditions, $stock_params);
					if(! $stock_update){
						$tr->rollBack();
						return $this->handleApiFormat(EnumOther::ACK_FAILURE, '','update stock pile failure');
					}
				}
				//分仓 --end
				
				//核算各个仓库中商品数量
				$res_account = $this->AccountStock($det ['product_id']);
				if(!$res_account){
					$tr->rollBack();
					return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'accounting stock_pile quantity fail');
				}
	
			}
			$tr->commit();
			return $this->handleApiFormat(EnumOther::ACK_SUCCESS,'');
		} catch ( \Exception $e ) {
			$tr->rollBack ();
			return $this->handleApiFormat(EnumOther::ACK_FAILURE,'',$e->getMessage());
		}
	}
	
	
	/**
	 * @desc 获取报盈汇总数据
	 * @author liaojianwen
	 * @date 2018-01-30
	 */
	public function getInventoryFullSummary($pageInfo, $cond)
	{
		if(empty($pageInfo)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'pageInfo is empty');
		}
		if(!isset($cond['starTime']) || empty($cond['starTime'])){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'search params time is empty');
		}
		$cond['starTime'] = strtotime($cond['starTime']);
		$cond['endTime'] = strtotime($cond['endTime']);
		$result =InventoryFullDetailDAO::getInstance()->getInventoryFullSummary($cond, $pageInfo);
		if(!$result){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'no data found');
		}
		return $this->handleApiFormat(EnumOther::ACK_SUCCESS, $result);
	}
	
	/**
	 * @desc 获取报损汇总数据
	 * @author liaojianwen
	 * @date 2018-01-30
	 */
	public function getInventoryLostSummary($pageInfo, $cond)
	{
		if(empty($pageInfo)){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'pageInfo is empty');
		}
		if(!isset($cond['starTime']) || empty($cond['starTime'])){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'search params time is empty');
		}
		$cond['starTime'] = strtotime($cond['starTime']);
		$cond['endTime'] = strtotime($cond['endTime']);
		$result =InventoryLostDetailDAO::getInstance()->getInventoryLostSummary($cond, $pageInfo);
		if(!$result){
			return $this->handleApiFormat(EnumOther::ACK_FAILURE, '', 'no data found');
		}
		return $this->handleApiFormat(EnumOther::ACK_SUCCESS, $result);
	}
}